package com.yuuko.yuukoapi.common.exception

import cn.dev33.satoken.exception.NotLoginException
import cn.dev33.satoken.exception.NotPermissionException
import cn.dev33.satoken.exception.NotRoleException
import cn.dev33.satoken.exception.SaTokenException
import com.yuuko.yuukoapi.common.response.AjaxResult
import com.yuuko.yuukoapi.common.response.None
import org.springframework.core.env.Environment
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.bind.annotation.ResponseStatus
import org.tinylog.Logger

@ControllerAdvice
@ResponseBody
class GlobalExceptionHandler(
    val env: Environment,
) {
    fun isDev(): Boolean {
        return env.activeProfiles.contains("dev")
    }

    @ExceptionHandler(Exception::class)
    fun exceptionHandler(e: Exception): AjaxResult<None?> {
        Logger.error("{}", e.stackTraceToString())
        return AjaxResult.fail(
            error = if (isDev()) e.stackTraceToString() else null
        )
    }

    @ExceptionHandler(BizException::class)
    fun bizExceptionHandler(e: BizException): AjaxResult<None?> {
        Logger.error("{}", e.stackTraceToString())
        return AjaxResult.fail(
            code = e.code?.code ?: -1,
            message = e.code?.message ?: "Business error",
            error = if (isDev()) e.stackTraceToString() else null
        )
    }

    @ExceptionHandler(NotLoginException::class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    fun notLoginExceptionHandler(e: NotLoginException): AjaxResult<None?> {
        Logger.error("{}", e.message)
        return AjaxResult.fail(
            code = ErrorCode.TOKEN_INVALID.code,
            message = ErrorCode.TOKEN_INVALID.message,
            error = if (isDev())e.stackTraceToString() else null
        )
    }

    @ExceptionHandler(NotPermissionException::class)
    fun notPermissionExceptionHandler(e: NotPermissionException): AjaxResult<None?> {
        Logger.error("{}", e.message)
        return AjaxResult.fail(
            code = ErrorCode.PERMISSION_ERROR.code,
            message = ErrorCode.PERMISSION_ERROR.message,
            error = if (isDev()) e.stackTraceToString() else null
        )
    }

    @ExceptionHandler(NotRoleException::class)
    fun notRoleExceptionHandler(e: NotRoleException): AjaxResult<None?> {
        Logger.error("{}", e.message)
        return AjaxResult.fail(
            code = ErrorCode.PERMISSION_ERROR.code,
            message = ErrorCode.PERMISSION_ERROR.message,
            error = if (isDev())e.stackTraceToString() else null
        )
    }

}